package com.AdvancedDemos.LearnThread多线程;

public class 线程创建方式二 {
    public static void main(String[] args) {
        /**
         * 多线程的创建方式二:实现Runnable接口
         *
         * ①定义一个线程任务类MyRunnable实现Runnable接口，重写run()方法
         * ②创建MyRunnable任务对象
         * ③把MyRunnable任务对象交给Thread处理。
         * public Thread(Runnable target) --- 封装Runnable对象成为线程对象
         * ④调用线程对象的start()方法启动线程
         */

        /**
         * 方式二的优缺点:
         * 优点:任务类只是实现接口，可以继续继承其他类、实现其他接口，扩展性强。
         * 缺点:需要多一个Runnable对象。
         */

        /*
        3.创建任务类对象
         */
        Runnable target = new MyRunnable();
        /*
        任务对象不是线程对象,不可以用任务对象调用start
        4.把任务对象交给一个线程对象处理
         */
        //public Thread(Runnable target)
        new Thread(target).start();


        /*5.线程创建方式二的匿名内部类写法(使用匿名内部类省去创建进程任务类)
        ①可以创建Runnable的匿名内部类对象。
        ②再交给Thread线程对象。
        ③再调用线程对象的start()启动线程。
         */
        //创建一个实现了Runnable接口的匿名内部类对象
        //重写run方法来给出进程任务
        new Thread(new Runnable() {
            //创建一个实现了Runnable接口的匿名内部类对象
            //重写run方法来给出进程任务
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println("匿名内部类中 子线程1 输出:" + i);
                }
            }
        }).start();

        new Thread(//进一步简化为Lambda表达式形式
                () -> {
                    for (int i = 0; i < 5; i++) {
                        System.out.println("匿名内部类中 子线程2 输出:" + i);
                    }
                }).start();


        //主线程中的任务应当放到子线程创立之后再执行
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程 输出:" + i);
        }

        //子线程 输出:0
        //匿名内部类中 子线程2 输出:0
        //主线程 输出:0
        //匿名内部类中 子线程1 输出:0
        //主线程 输出:1
        //匿名内部类中 子线程2 输出:1
        //子线程 输出:1
        //子线程 输出:2
        //子线程 输出:3
        //子线程 输出:4
        //匿名内部类中 子线程2 输出:2
        //主线程 输出:2
        //匿名内部类中 子线程1 输出:1
        //主线程 输出:3
        //匿名内部类中 子线程2 输出:3
        //主线程 输出:4
        //匿名内部类中 子线程1 输出:2
        //匿名内部类中 子线程2 输出:4
        //匿名内部类中 子线程1 输出:3
        //匿名内部类中 子线程1 输出:4


    }
}

/*
1.定义一个任务类,实现Runnable接口
 */
class MyRunnable implements Runnable {
    /*
    2.重写run方法,给出线程执行的任务
     */
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程 输出:" + i);
        }
    }
}
